Django

您所在的位置:网站首页 django forms传instance Django

Django

#Django| 来源: 网络整理| 查看: 265

文章目录 ModelFormModel写法以及自定义错误信息save方法 文件上传前端HTML代码实现后端的代码实现使用模型的方式来处理上传的文件指定MEDIA_ROOT和MEDIA_URL限制文件的文件拓展名

ModelForm Model写法以及自定义错误信息

大家在写表单的时候,会发现表单中的Field和模型中的Field基本上是一模一样的,而且表单中需要验证的时候,也就是我们模型中需要保存的数据,我们可以在表单中可以从from django import froms下的froms.ModelForm来进行绑定字段

导入:from django import froms定义的类要继承于forms.ModelFrom在类中定义meta对应的类,该类的写法是固定的 model : 对应的模型fields : 验证的字段 。当需要验证全部字段时: __all__ : 代表着为验证全部字段 ,[] :代表着只需要验证的字段exclude : 不验证的字段。表示不验证该字段error_messages : 自定义错误信息

forms.py

# @Time : 2020/7/21 0:18 # @Author : Small-J from django import forms from .models import Article # forms.Form:代表着为导入表单 # forms.ModelForm:代表着导入模型的表单 class AddForms(forms.ModelForm): """ Meta : 该类是必须继承的,但是该字段是 model :对应的模型类 fields : 当为‘__all__就是验证全部字段’,当只想验证其中部分的字段的时候,需要使用[]包裹起来 """ class Meta: model = Article # fields = '__all__' # 当只想验证某几个字段的情况下可以使用[]的形式 # fields = ['title'] # 表示只验证title这个字段 exclude = ['title'] # exclude->排除的意思 表示不验证title这个字段 error_messages = { 'title': { 'required': '该字段是必须要填的', 'min_length': '最小长度为3', 'max_length': '最大长度为20' }, 'content': { 'required': '该字段是必须要填的', 'max_length': '最大长度为100' }, 'author': { 'required': '该字段是必须要填的', 'max_length': '最大长度为15' } }

views.py

from django.shortcuts import render from django.views import View # 导入表单验证 from .forms import AddForms from django.http import HttpResponse class AddArticle(View): def get(self, request): return render(request, 'add.html') def post(self, request): form = AddForms(request.POST) # is_valid:代表验证通过的情况下 if form.is_valid(): return HttpResponse('success') else: print(form.errors.get_json_data()) return HttpResponse('fail')

add.html

Title {# csrf_token:代表着解除csrf的一个保护 #} {% csrf_token %} 标题: 内容: 作者:

models.py

from django.db import models # 自定义验证器 from django.core import validators class Article(models.Model): # 当我们想设置最小长度的时候,但是在字段中没有的话,可以借助自定义验证器 # MinLengthValidator title = models.CharField(max_length=20, validators=[validators.MinLengthValidator(limit_value=3)]) content = models.TextField(max_length=100, validators=[validators.MinLengthValidator(limit_value=3)]) author = models.CharField(max_length=15) create_time = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'article'

app/urls.py

# @Time : 2020/7/21 0:11 # @Author : Small-J from . import views from django.urls import path urlpatterns = [ path('', views.AddArticle.as_view()) ] save方法

ModelForm还有save方法,可以验证完成后直接调用save方法,就可以将这个数据库保存到数据库中

from django.shortcuts import render from django.views import View # 导入表单验证 from .forms import AddForms from django.http import HttpResponse class AddArticle(View): def get(self, request): return render(request, 'add.html') def post(self, request): form = AddForms(request.POST) # is_valid:代表验证通过的情况下 if form.is_valid(): # 接收请求并保存到数据库 form.save() # 保存完之后在数据库中显示正常 return HttpResponse('success') else: print(form.errors.get_json_data()) return HttpResponse('fail')

这个方法必须要在clean没有问题后才能使用,如果在clean之前使用,会抛出异常。另外,我们在调用save方法的时候,如果传入一个commit=False,那么只会生成这个模型的对象,而不会把这个对象真正的插入到数据库中。比如表单上验证的字段没有包含模型中所有的字段,这时候就可以先创建对象,再根据填充其他字段,把所有字段的只都补充完成后,再保存到数据库中。

views.py

class RegisterArticle(View): def get(self, request): return render(request, 'register.html') def post(self, request): form = RegisterForm(request.POST) if form.is_valid(): user = form.save() user.password = form.cleaned_data.get('pwd1') user.save() return HttpResponse('注册成功') else: print(form.errors.get_json_data()) return HttpResponse('fail')

forms.py

class RegisterForm(forms.ModelForm): pwd1 = forms.CharField(min_length=3, max_length=10) pwd2 = forms.CharField(min_length=3, max_length=10) email = forms.EmailField() # clean映射多字段 def clean(self): changed_data = super().clean() # print(changed_data) # 该返回的是一个字典形式 # changed_data:该返回是有变化的列表 pwd1 = changed_data.get('pwd1') pwd2 = changed_data.get('pwd2') if pwd1 != pwd2: raise forms.ValidationError('请输入两次相同的密码') class Meta: # 使用的模型 model = Register # 不验证密码 exclude = ['password'] error_messages = { 'telephone': { 'required': '请填写该字段', }, 'email': { 'required': '请填写该字段', 'invalid': '请输入正确的邮箱地址' } }

models.py

class Register(models.Model): # 当不能设置最小长度的时候,可以使用自定义验证器来弄最小长度值 # 对应的字段里面都会对应的自定义验证器使用 username = models.CharField(max_length=10, validators=[validators.MinLengthValidator(limit_value=3)]) password = models.CharField(max_length=10, validators=[validators.MinLengthValidator(limit_value=3)]) telephone = models.CharField(max_length=11, validators=[validators.RegexValidator(r'1[3456789]\d{9}', message='请输入正确的手机号码')]) email = models.CharField(max_length=20, validators=[validators.EmailValidator(message='请输入正确的邮箱地址')]) class Meta: db_table = 'register'

urls.py

from . import views from django.urls import path urlpatterns = [ path('register/', views.RegisterArticle.as_view()) ]

register.html

Title {% csrf_token %} 用户: 密码: 再次输入密码: 电话 邮箱

在这里插入图片描述

文件上传

完成文件上传必须完成两部分,一部分是前端页面,另外一部分是后端页面

前端HTML代码实现 在前端中,我们需要填入一个form标签,然后在这个form标签中指定enctype="multipart/form-data",不然就不能上传文件。在form标签中添加一个input标签,然后指定input标签的name,以及type="file" Title {% csrf_token %} 后端的代码实现

后端的主要工作是接收文件。然后存储文件。接收文件的方式跟接收POST的方式是一样的,只不过是通过FILES来实现的

注意: images = request.FILES.get('images') 该对应的是一个类,当我们想读取里面的内容出来的时候需要使用到read()来读取 class UploadFiles(View): def get(self, request): return render(request, 'upload.html') def post(self, request): # print(request.POST) # 当选择文件上传的时候,应该选择的是FILES该文件 print(request.FILES) # images = request.FILES.get('images') print(images) # thumb-1920-771788.png 打印的是图片的名字 print(type(images)) # 但是这张图片是一个类 with open('demo.png', 'wb')as f: f.write(images.read()) return HttpResponse('success') 使用模型的方式来处理上传的文件

在定义模型的时候,我们可以给存储文件字段指定为FileField,这个Field可以传递一个upload_toc参数,用来指定上传上来的文件保存到哪里。当upload_to="file"的时候,对应的参数会保存到file这个文件夹下。注意:(当上传的文件的名字一样的话,对应的Django会帮助我们处理好图片,并不会覆盖)

models.py

class Article(models.Model): # 当我们想设置最小长度的时候,但是在字段中没有的话,可以借助自定义验证器 # MinLengthValidator title = models.CharField(max_length=20, validators=[validators.MinLengthValidator(limit_value=3)]) content = models.TextField(max_length=100, validators=[validators.MinLengthValidator(limit_value=3)]) author = models.CharField(max_length=15) create_time = models.DateTimeField(auto_now_add=True) # FileField 为文件上传功能 # upload_to:对应的files创建的文件夹目录 images = models.FileField(upload_to='files', null=True) class Meta: db_table = 'article'

views.py

class UploadFiles(View): def get(self, request): return render(request, 'upload.html') def post(self, request): # print(request.POST) # 当选择文件上传的时候,应该选择的是FILES该文件 # print(request.FILES) # # images = request.FILES.get('images') # print(images) # thumb-1920-771788.png 打印的是图片的名字 # print(type(images)) # 但是这张图片是一个类 # with open('demo.png', 'wb')as f: # f.write(images.read()) # ---------------------------------------------------------------- title = request.POST.get('title') content = request.POST.get('content') author = request.POST.get('author') create_time = request.POST.get('create_time') # 当接收文件的时候使用的是FILES这个文件方式来进行接收 images = request.FILES.get('images') article = Article(title=title, content=content, author=author, images=images) article.save() return HttpResponse('success')

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

指定MEDIA_ROOT和MEDIA_URL

以上我们是使用了upload_to来指定上传的文件的目录。我们也可以指定MEDIA_ROOT,就不需要在FielField中指定upload_to,他会自动的将文件上传到MEDIA_ROOT的目录下

MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'

在urls.py中添加MEDIA_ROOT目录下的访问路径

from django.urls import path from front import views from django.conf.urls.static import static from django.conf import settings urlpatterns = [ path('', views.index), ] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

如果我们同时知道MEDIA_ROOT和upload_to,那么会将文件上传到MEDIA_ROOT下的upload_to文件夹中

upload_to : %Y/%M/%D

这样写的好处是在于对图片的一个进行分类 class Article(models.Model): # 当我们想设置最小长度的时候,但是在字段中没有的话,可以借助自定义验证器 # MinLengthValidator title = models.CharField(max_length=20, validators=[validators.MinLengthValidator(limit_value=3)]) content = models.TextField(max_length=100, validators=[validators.MinLengthValidator(limit_value=3)]) author = models.CharField(max_length=15) create_time = models.DateTimeField(auto_now_add=True) # FileField 为文件上传功能 # upload_to:对应的files创建的文件夹目录 images = models.FileField(upload_to='%Y/%M/%D', null=True) class Meta: db_table = 'article'

在这里插入图片描述

限制文件的文件拓展名

如果想要限制上传的文件的拓展名,那么我们就需要用到表单来进行限制。我们可以使用普通的Form表单,也可以使用ModelForm,直接从模型中读取字段。注意:(当进行文件上传的时候,通过表单验证的时候,需要在对应的参数上面加上request.FILES),使用ImageField必须要安装pip install Pillow

models.py

class Article(models.Model): # 当我们想设置最小长度的时候,但是在字段中没有的话,可以借助自定义验证器 # MinLengthValidator title = models.CharField(max_length=20, validators=[validators.MinLengthValidator(limit_value=3)]) content = models.TextField(max_length=100, validators=[validators.MinLengthValidator(limit_value=3)]) author = models.CharField(max_length=15) create_time = models.DateTimeField(auto_now_add=True) # FileField 为文件上传功能 # upload_to:对应的files创建的文件夹目录 # 自定义验证器对文件上传做相对应的数据验证 # FileExtensionValidator:对应的限制文件上传 # ImageField :默认只允许让你传相对应的图片文件 pip install Pillow images = models.ImageField(upload_to='%Y/%m/%d', null=True, validators=[validators.FileExtensionValidator(['jpg', 'png'])]) class Meta: db_table = 'article'

views.py

class UploadFiles(View): def get(self, request): return render(request, 'upload.html') def post(self, request): # print(request.POST) # 当选择文件上传的时候,应该选择的是FILES该文件 # print(request.FILES) # # images = request.FILES.get('images') # print(images) # demo.png 打印的是图片的名字 # print(type(images)) # 但是这张图片是一个类 # with open('demo.png', 'wb')as f: # f.write(images.read()) # ---------------------------------------------------------------- # 当对应需要验证表单和FIELD的时候,需要进行在对应的上面加上参数 form = UploadForm(request.POST, request.FILES) if form.is_valid(): title = request.POST.get('title') content = request.POST.get('content') author = request.POST.get('author') create_time = request.POST.get('create_time') # 当接收文件的时候使用的是FILES这个文件方式来进行接收 images = request.FILES.get('images') article = Article(title=title, content=content, author=author, images=images) article.save() return HttpResponse('success') else: print(form.errors.get_json_data()) return HttpResponse('fail')

forms.py

class UploadForm(forms.ModelForm): class Meta: # 表单验证的一个模型 model = Article fields = '__all__' error_messages = { 'images': { 'invalid_extension': '只能上传png和jpg文件格式' } }

upload.html

Title {% csrf_token %} 标题: 内容: 作者: 文件上传:

在这里插入图片描述

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3